package com.zyl.blog.common.utils.Extreme;

import com.zyl.blog.common.config.TreeConfig;
import com.zyl.blog.common.service.ITreeNode;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @version v1.0
 * @ProjectName: Personal_Blog
 * @Package: com.zyl.common.utils.Extreme
 * @ClassName: TreeUtils
 * @Description: 树工具类（支持泛型ID）
 * @Author FinalFantasy
 * @Date 2025/2/19-10:14
 */
public class TreeUtils {
    // 查找指定节点（支持泛型ID）
    public static <T> ITreeNode<T> findNode(
            List<ITreeNode<T>> tree, T targetId) {
        for (ITreeNode<T> node : tree) {
            if (Objects.equals(node.getId(), targetId)) return node;
            ITreeNode<T> found = findNode(node.getChildren(), targetId);
            if (found != null) return found;
        }
        return null;
    }

    // 扁平化树结构（支持泛型ID）
    public static <ID> List<ITreeNode<ID>> flattenTree(
            List<ITreeNode<ID>> tree) {
        List<ITreeNode<ID>> result = new ArrayList<>();
        tree.forEach(node -> {
            result.add(node);
            result.addAll(flattenTree(node.getChildren()));
        });
        return result;
    }

    // 权限树转角色树适配器（保持Long类型，如需要可改为泛型）
    public static List<ITreeNode<Long>> convertTreeType(
            List<? extends ITreeNode<Long>> source) {
        return source.stream()
                .map(node -> (ITreeNode<Long>) node)
                .collect(Collectors.toList());
    }

    /**
     * 通用树构建方法（支持泛型ID）
     * @param list 原始数据列表
     * @param config 配置对象（包含ID类型信息）
     * @return 树形结构
     */
    public static <T extends Serializable, ID> List<T> buildTree(List<T> list, TreeConfig<T, ID> config) {
        return buildTree(
                list,
                config.getIdGetter(),
                config.getParentIdGetter(),
                config.getChildrenGetter(),
                config.getChildrenSetter(),
                config.getComparators()
        );
    }

    /**
     * 通用树构建方法（完全泛型版）
     * @param list 原始数据列表
     * @param idGetter 节点ID提取器
     * @param parentIdGetter 父节点ID提取器
     * @param childrenGetter 子节点列表获取器
     * @param childrenSetter 子节点列表设置器
     * @param comparator 排序比较器（可选）
     * @return 树形结构
     */
    public static <T, ID> List<T> buildTree(
            List<T> list,
            Function<T, ID> idGetter,
            Function<T, ID> parentIdGetter,
            Function<T, List<T>> childrenGetter,
            BiConsumer<T, List<T>> childrenSetter,
            Comparator<T> comparator) {
        if (CollectionUtils.isEmpty(list)) return Collections.emptyList();

        // 使用LinkedHashMap保持插入顺序，键类型改为ID泛型
        Map<ID, T> nodeMap = new LinkedHashMap<>(list.size());

        // 初始化所有节点并预置空子列表
        list.forEach(node -> {
            if (childrenGetter.apply(node) == null) {
                childrenSetter.accept(node, new ArrayList<>());
            }
            nodeMap.put(idGetter.apply(node), node);
        });

        // 构建树结构
        List<T> roots = new ArrayList<>();
        nodeMap.forEach((_, node) -> {
            ID parentId = parentIdGetter.apply(node);
            // 处理根节点判断（null或特定根标识）
            if (parentId == null || (parentId instanceof Number && ((Number) parentId).longValue() <= 0)) {
                roots.add(node);
            } else {
                T parent = nodeMap.get(parentId);
                if (parent != null) {
                    List<T> siblings = childrenGetter.apply(parent);
                    siblings.add(node);
                } else {
                    roots.add(node); // 处理孤儿节点
                }
            }
        });

        // 排序处理
        if (comparator != null) {
            sortTree(roots, childrenGetter, comparator);
        }

        return roots;
    }

    /**
     * 类型安全的树排序方法
     */
    private static <T> void sortTree(
            List<T> nodes,
            Function<T, List<T>> childrenGetter,
            Comparator<T> comparator
    ) {
        if (CollectionUtils.isEmpty(nodes) || comparator == null) return;

        // 当前层排序
        nodes.sort(comparator);

        // 递归子节点排序
        nodes.forEach(node -> {
            List<T> children = childrenGetter.apply(node);
            if (!CollectionUtils.isEmpty(children)) {
                sortTree(children, childrenGetter, comparator);
            }
        });
    }

    /**
     * 带类型转换的树构建方法（支持泛型ID）
     */
    public static <T, R, ID> List<R> buildTreeWithConversion(
            List<T> sources,
            Function<T, R> converter,
            Function<R, ID> idGetter,
            Function<R, ID> parentIdGetter,
            BiConsumer<R, List<R>> childrenSetter,
            Comparator<R> comparator
    ) {
        List<R> targets = sources.stream()
                .map(converter)
                .collect(Collectors.toList());

        return buildGenericTree(
                targets,
                idGetter,
                parentIdGetter,
                childrenSetter,
                comparator
        );
    }

    /**
     * 独立泛型方法实现（支持泛型ID）
     */
    private static <R, ID> List<R> buildGenericTree(
            List<R> list,
            Function<R, ID> idGetter,
            Function<R, ID> parentIdGetter,
            BiConsumer<R, List<R>> childrenSetter,
            Comparator<R> comparator
    ) {
        Map<ID, R> nodeMap = new LinkedHashMap<>(list.size());

        list.forEach(node -> {
            childrenSetter.accept(node, new ArrayList<>());
            nodeMap.put(idGetter.apply(node), node);
        });

        List<R> roots = new ArrayList<>();
        nodeMap.forEach((_, node) -> {
            ID parentId = parentIdGetter.apply(node);
            // 根节点判断逻辑适配泛型
            if (parentId == null || (parentId instanceof Number && ((Number) parentId).longValue() <= 0)) {
                roots.add(node);
            } else {
                R parent = nodeMap.get(parentId);
                if (parent != null) {
                    List<R> children = new ArrayList<>();
                    // 先获取父节点已有子节点
                    // 注意：这里假设childrenSetter同时也能用于获取，实际可能需要调整
                    childrenSetter.accept(parent, children);
                    children.add(node);
                } else {
                    roots.add(node);
                }
            }
        });

        if (comparator != null) {
            sortGenericTree(roots, childrenSetter, comparator);
        }

        return roots;
    }

    /**
     * 泛型排序方法
     */
    private static <R> void sortGenericTree(
            List<R> nodes,
            BiConsumer<R, List<R>> childrenSetter,
            Comparator<R> comparator
    ) {
        if (CollectionUtils.isEmpty(nodes)) return;

        nodes.sort(comparator);

        nodes.forEach(node -> {
            List<R> children = new ArrayList<>();
            childrenSetter.accept(node, children);
            if (!CollectionUtils.isEmpty(children)) {
                sortGenericTree(children, childrenSetter, comparator);
            }
        });
    }
}
